package com.cnblog.blog.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.w3c.dom.Entity;

public class HttpUtility {
	public static final int connectTimeOut = 10000;
	public static final int socketTimeOut = 10000;
	
	public static String httpGetString(String url) throws ClientProtocolException, IOException {
		return httpGetString(url,null);
	}
	
	public static InputStream httpGetInputStream(String url) throws ClientProtocolException, IOException {
		return httpGetInputStream(url,null);
	}
	
	public static String httpPostString(String url, List<NameValuePair> postData, String dataEncoding) throws ClientProtocolException, IOException {
		return httpPostString(url,null,postData, dataEncoding);
	}
	
	public static String httpGetString(String url,Map<String, String> heads) throws ClientProtocolException, IOException {
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeOut);
		HttpConnectionParams.setSoTimeout(httpParameters, socketTimeOut);
		DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
		HttpGet getMethod = new HttpGet(url);
		if(heads != null) {
			for(Entry<String, String> entry : heads.entrySet()) {
				getMethod.addHeader(entry.getKey(), entry.getValue());
			}
		}
		HttpResponse resp = httpClient.execute(getMethod);
		int status = resp.getStatusLine().getStatusCode();
		if(status != HttpStatus.SC_OK) {
			return "";
		}
		HttpEntity entity = resp.getEntity();
		String charset = getContentCharset(resp);
		String result = StringUtil.inputStream2String(entity.getContent(), charset);
		return result;
	}
	
	public static InputStream httpGetInputStream(String url, Map<String,String> heads) throws ClientProtocolException, IOException {
		HttpParams httpParams = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParams, connectTimeOut);
		HttpConnectionParams.setSoTimeout(httpParams, socketTimeOut);
		DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
		HttpGet getMethod = new HttpGet(url);
		if(heads != null) {
			for(Entry<String,String> entry : heads.entrySet()) {
				getMethod.addHeader(entry.getKey(), entry.getValue());
			}
		}
		HttpResponse resp = httpClient.execute(getMethod);
		int status = resp.getStatusLine().getStatusCode();
		if(status != HttpStatus.SC_OK) {
			throw new IOException("http code = " + status);
		}
		HttpEntity entity = resp.getEntity();
		InputStream stream = entity.getContent();
		return stream;
	}
	
	public static String httpPostString(String url,Map<String,String> heads, List<NameValuePair> postData, String dataEncoding) throws ClientProtocolException, IOException {
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeOut);
		HttpConnectionParams.setSoTimeout(httpParameters, socketTimeOut);
		DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
		HttpPost postMethod = new HttpPost(url);
		if(heads != null) {
			for(Entry<String,String> entry : heads.entrySet()) {
				postMethod.addHeader(entry.getKey(),entry.getValue());
			}
		}
		HttpEntity httpEntity = null;
		if(postData != null) {
			if(dataEncoding == null || dataEncoding.length() == 0) {
				dataEncoding = "utf-8";
			}
			httpEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postData,dataEncoding);
		}
		if(httpEntity != null) {
			postMethod.setEntity(httpEntity);
		}
		HttpResponse resp = httpClient.execute(postMethod);
		int status = resp.getStatusLine().getStatusCode();
		if(status != HttpStatus.SC_OK) {
			return "";
		}
		HttpEntity entity = resp.getEntity();
		String charset = getContentCharset(resp);
		String result = StringUtil.inputStream2String(entity.getContent(), charset);
		return result;
	}

	public static InputStream httpPostInputStream(String url,Map<String,String> heads ,List<NameValuePair> postData,String dataEncoding) throws ClientProtocolException, IOException {
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeOut);
		HttpConnectionParams.setSoTimeout(httpParameters, socketTimeOut);
		DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
		HttpPost postMethod = new HttpPost(url);
		if(heads != null) {
			for(Entry<String,String> entry : heads.entrySet()) {
				postMethod.addHeader(entry.getKey(),entry.getValue());
			}
		}
		HttpEntity httpEntity = null;
		if(postData != null) {
			if(dataEncoding == null || dataEncoding.length() == 0) {
				dataEncoding = "utf-8";
			}
			httpEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postData,dataEncoding);
		}
		if(httpEntity != null) {
			postMethod.setEntity(httpEntity);
		}
		HttpResponse resp = httpClient.execute(postMethod);
		int status = resp.getStatusLine().getStatusCode();
		if(status != HttpStatus.SC_OK) {
			throw new IOException("http code = " + status);
		}
		HttpEntity entity = resp.getEntity();
		InputStream stream = entity.getContent();
		return stream;
	};
	
	public static int httpHead(String url,Map<String,String> heads) throws ClientProtocolException, IOException {
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeOut);
		HttpConnectionParams.setSoTimeout(httpParameters, socketTimeOut);
		DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
		HttpHead headMethod = new HttpHead(url);
		if(heads != null) {
			for(Entry<String, String> entry : heads.entrySet()) {
				headMethod.addHeader(entry.getKey(),entry.getValue());
			}
		}
		HttpResponse resp = httpClient.execute(headMethod);
		int status = resp.getStatusLine().getStatusCode();
		return status;
	}
	
	public static String getEncodeString(String str,String encoder) throws UnsupportedEncodingException {
		if(encoder == null || encoder.length() == 0) {
			encoder = "utf-8";
		}
		return URLEncoder.encode(str, encoder);
	}
	
	private static String getContentCharset(HttpResponse resp) {
		String charset = "ISO-8859-1";
		HttpEntity entity = resp.getEntity();
		org.apache.http.Header header = entity.getContentType();
		if(header != null) {
			String s = header.getValue();
			if(StringUtil.matcher(s, "(charset)\\s?=\\s?(utf-?8)")) {
				charset = "utf-8";
			} else if(StringUtil.matcher(s, "(charset)\\s?=\\s?(gbk)")) {
				charset = "gbk";
			} else if(StringUtil.matcher(s, "(charset)\\s?=\\s?(gb2312)")) {
				charset = "gb2312";
			}
		}
		return charset;
	}
}

